using System;
using System.Web;
using System.Web.Security;
using ClientTools.Library;
using umbraco;
using umbraco.BusinessLogic;

namespace ClientTools.Server.Webservices
{
    public class ClientToolsBaseService : System.Web.Services.WebService
    {
        protected User UmbracoUser;

        /// <summary>
        /// Authenticates the specified user.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="password">The password.</param>
        /// <param name="service">The type of service.</param>
        /// <returns></returns>
        protected User Authenticate(string userName, string password, ServiceTypeEnum service)
        {
            // first check if Username and Password is given...
            if (userName.IsTrimmedNullOrEmpty() || password.IsTrimmedNullOrEmpty())
                throw new Exceptions.NotAllCredentialsGivenException();

            var configFilePath = HttpContext.Current.Server.MapPath("/config/ClientTools.config");
            if (!System.IO.File.Exists(configFilePath))
                throw new Exceptions.ConfigurationNotFoundException();

            // first step of authentication is to verify the user against the umbraco user
            // ReSharper disable PossibleNullReferenceException
            if (!Membership.Providers[UmbracoSettings.DefaultBackofficeProvider].ValidateUser(userName, password))
                // ReSharper restore PossibleNullReferenceException
                throw new Exceptions.IncorrectCredentialsException();

            UmbracoUser = new User(userName);
            // check if the user has acces to the umbraco backend
            if (UmbracoUser.NoConsole || UmbracoUser.Disabled)
                throw new Exceptions.UserDisabledException();

            // now check if the user is configured
            // First get the ConfigObject: Read all the settings from ClientTools.config
            var config = ConfigClasses.Config.Current;

            // Check if the config is enabled
            if (config.Enabled == false)
                throw new Exceptions.ConfigurationDisbaledException();

            // Get the related user from the ConfigObject
            var user = config.GetUserByName(userName);
            if (user == null)
                throw new Exceptions.UserNotConfiguredException();

            // Check if the user is enabled
            if (user.Enabled == false)
                throw new Exceptions.UserDisabledException();

            // Dependend on which service is selected...
            switch (service)
            {
                case ServiceTypeEnum.MaintenanceService:
                    if (user.MaintenanceService == null || !user.MaintenanceService.Enabled)
                        throw new Exceptions.ServiceDisabledException();
                    break;
                case ServiceTypeEnum.MediaService:
                    if (user.MediaService == null || !user.MediaService.Enabled || !IsUserAllowedForApplication(UmbracoUser, "media"))
                        throw new Exceptions.ServiceDisabledException();
                    break;
                //case ServiceTypeEnum.PackageService:
                //    if (user.PackageService == null || !user.PackageService.Enabled)
                //        throw new Exceptions.ServiceDisabledException();
                //    break;
                default:
                    return null;
            }
            return UmbracoUser;
        }

        /// <summary>
        /// Determines whether the user is allowed for the named application.
        /// </summary>
        /// <param name="umbracoUser">The umbraco user.</param>
        /// <param name="appAlias">The application alias.</param>
        /// <returns>
        /// 	<c>true</c> if user is allowed for the named application otherwise, <c>false</c>.
        /// </returns>
        private static bool IsUserAllowedForApplication(User umbracoUser, String appAlias)
        {
            foreach (var app in umbracoUser.Applications)
                if (app.alias == appAlias)
                    return true;
            return false;
        }

    }
}
